home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
gepackte_disketten
/
1993
/
02_93_2.dms
/
02_93_2.adf
/
Devices (Folge 4)
/
ConDev.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-08
|
13KB
|
474 lines
/* ConDev.c
richtet eine --- Shell --- fuer die Arbeit mit dem
Console Device ein.
Autor: E.G. Meyzis, Mai 1992
Compile Instr. fuer DICE:
dcc ConDev.c -c -o t:ConDev.o
Link Instr. fuer DICE:
dlink dlib:c.o t:ConDev.o dlib:c.lib+
dlib:amigas20.lib dlib:auto.lib dlib:x.o -o ConDev
*/
#include <Devices/Console.h>
#include <Devices/ConUnit.h>
#include <Dos/Dos.h>
#include <Exec/Exec.h>
#include <Intuition/Intuition.h>
#include <stdlib.h>
#include <stdio.h>
#include <utility/TagItem.h>
/* +++++++++ Definitionen ++++++++++++
*/
#define TRUE 1 /* um mit Datentyp BOOL zu arbeiten */
#define FALSE 0
#define CSI 0x9B /* Control Sequence Introducer, wie z.B.
fuer F-Tasten F1 bis F10 verwendet */
#define OS200 36 /* mindestens OS 2.0 */
#define ConTitle " Con Dev " /* Titel Console Window */
/* +++++++++ Datentypen ++++++++++++
*/
typedef char BOOL;
typedef char *CharPtr;
typedef struct IOStdReq *IOStdReqPtr;
typedef struct Window *WindowPtr;
typedef struct MessagePort *MsgPortPtr;
/* ++++++++ Routinen des Basisprogramms ++++++++++ */
BOOL RunningOS2();
void IORequestAbbauen(IOStdReqPtr reqPtr);
void Aufraeumen();
BOOL FensterAngelegt(WindowPtr *win);
BOOL ConsoleEingerichtet(IOStdReqPtr *wrPtr, *rdPtr,
WindowPtr winPtr);
BOOL IORequestAngelegt(IOStdReqPtr *conPtr);
void ConWriteStr(IOStdReqPtr conPtr, CharPtr str);
void ConWriteBuf(IOStdReqPtr conPtr,
CharPtr bufPtr,
int laenge);
int ConReadSync(IOStdReqPtr conPtr,
CharPtr bufPtr,
int laenge);
BOOL ConReadASync(IOStdReqPtr conPtr,
CharPtr bufPtr,
int laenge);
void IDCMPCloseClickAbholen(WindowPtr winPtr);
/* ++++++++ Demo- und Test-Routinen ++++++++++ */
void SchreibTest();
void LeseTest();
void LeseRawEvent();
void EventCloseClickAbholen(IOStdReqPtr conPtr);
void ANSICodeDemo();
/* +++++++++ globale Variablen ++++++++++++
*/
WindowPtr ourWinPtr;
/* Ein Device, zwei I/O Strukturen */
IOStdReqPtr conWritePtr, /* Schreiben */
conReadPtr; /* Lesen */
int main()
{
int returnVal = 0; /* erfolgreiche Ausfuehrung annehmen */
if (RunningOS2()) /* dann haben wir mindestens OS 2.0 */
{
if(FensterAngelegt(&ourWinPtr))
{
if (ConsoleEingerichtet (&conWritePtr,
&conReadPtr, ourWinPtr))
{
SchreibTest();
ANSICodeDemo();
LeseTest();
LeseRawEvent();
IDCMPCloseClickAbholen(ourWinPtr); /* warten */
}
else
returnVal = 10; /* Console Dev. nicht anlegbar */
} /* Fenster ... */
else
returnVal = 11; /* Window nicht anlegbar */
Aufraeumen();
} /* Running ... */
else
returnVal = 12; /* OS 1.2/1.3 */
return returnVal;
}
BOOL RunningOS2() /* lauft Programm unter OS 2.x ? */
{
long *systemBasis;
struct ExecBase *execBasePtr;
systemBasis = (APTR)4; /* Adr ExecBase a. Adr. 4 holen */
execBasePtr = (APTR)*systemBasis;
if (execBasePtr->LibNode.lib_Version >= OS200) /* OS 2 */
return TRUE;
else
return FALSE;
}
void Aufraeumen() /* Ressourcen freigeben */
{
if (conReadPtr) /* Lese- I/O Struktur */
{
if (!CheckIO(conReadPtr)) /* laeuft ein I/O Req.? */
{
AbortIO(conReadPtr); /* falls ja, diesen abbrechen*/
WaitIO(conReadPtr); /* und auf Beendigung warten */
}
IORequestAbbauen(conReadPtr); /* einschl. Msg Port */
}
if (conWritePtr)
{
if (conWritePtr->io_Device)
CloseDevice(conWritePtr);
IORequestAbbauen(conWritePtr);
}
if (ourWinPtr)
{
CloseWindow(ourWinPtr);
ourWinPtr = 0;
}
}
void IORequestAbbauen(IOStdReqPtr reqPtr)
{
if (reqPtr->io_Message.mn_ReplyPort)
{ /* OS 2 */
DeleteMsgPort(reqPtr->io_Message.mn_ReplyPort);
}
DeleteIORequest(reqPtr); /* OS 2 */
reqPtr = 0;
}
BOOL FensterAngelegt(WindowPtr *win)
{
static struct TagItem tagBuffer[10] = /* OS 2 */
{
WA_Left, 20,
/* DICE ver- */ WA_Top, 20,
/* langt es, */ WA_Title, (ULONG*) ConTitle,
/* die Struk-*/ WA_Width, 500,
/* tur, glo- */ WA_Height, 200,
/* bal oder */ WA_MinWidth, 100,
/* static an */ WA_MinHeight, 50,
/* zulegen */ WA_Flags, WFLG_SIMPLE_REFRESH |
WFLG_CLOSEGADGET |
WFLG_DEPTHGADGET |
WFLG_DRAGBAR |
WFLG_SIZEGADGET,
TAG_DONE
};
*win = (WindowPtr)OpenWindowTagList (NULL, tagBuffer);
return (*win != NULL);
}
BOOL ConsoleEingerichtet(IOStdReqPtr *wrPtr, *rdPtr,
WindowPtr winPtr)
{
IOStdReqPtr writePtr,
readPtr;
BOOL done = FALSE;
if (IORequestAngelegt(&writePtr)) /* 1. I/O struktur */
{
writePtr->io_Data = winPtr; /* Intuition Window */
writePtr->io_Length = sizeof(struct Window);
OpenDevice("console.device", CONU_STANDARD, /* OS 2 */
writePtr, CONFLAG_DEFAULT);
if ((!writePtr->io_Error) && /* Device geoeffnet */
(IORequestAngelegt(&readPtr)))
{
readPtr->io_Unit = writePtr->io_Unit; /* 2. Strukt*/
readPtr->io_Device = writePtr->io_Device; /* erbt */
done = TRUE;
*wrPtr = writePtr; /* Zeiger auf I/O Strukturen */
*rdPtr = readPtr; /* ans rufende Prog. geben */
}
else
Aufraeumen; /* mangelte es an RAM? */
}
return done;
}
BOOL IORequestAngelegt(IOStdReqPtr *conPtr)
{
MsgPortPtr portPtr;
BOOL done = FALSE;
portPtr = (MsgPortPtr)CreateMsgPort(); /* OS2 */
if (portPtr)
{
*conPtr = (IOStdReqPtr)
CreateIORequest(portPtr, /* OS 2 */
sizeof(struct IOStdReq));
if (*conPtr)
done = TRUE;
else
DeleteMsgPort(portPtr); /* OS 2 */
}
return done;
}
void ConWriteStr(IOStdReqPtr conPtr, CharPtr str)
{
conPtr->io_Data = str;
conPtr->io_Length = -1; /* nur f. mit 0 termin. Strings */
conPtr->io_Command = CMD_WRITE;
DoIO(conPtr);
}
void ConWriteBuf(IOStdReqPtr conPtr,
CharPtr bufPtr, /*m. auszugeb. Zeich.*/
int laenge) /* Zeichenanzahl */
{
conPtr->io_Data = bufPtr;
conPtr->io_Length = laenge; /* beliebige Laenge */
conPtr->io_Command = CMD_WRITE;
DoIO(conPtr);
}
int ConReadSync(IOStdReqPtr conPtr,
CharPtr bufPtr, /* dort hin lesen */
int laenge) /* Anzahl der Zeichen */
{
conPtr->io_Data = bufPtr;
conPtr->io_Length = laenge;
conPtr->io_Command = CMD_READ;
SendIO(conPtr);
WaitIO(conPtr); /* nur unter OS 2 sicher */
return conPtr->io_Actual;
}
BOOL ConReadASync(IOStdReqPtr conPtr, /*asynchrones Lesen */
CharPtr bufPtr, /* ist das empfohle-*/
int laenge) /*ne Verfahren */
{
conPtr->io_Data = bufPtr;
conPtr->io_Length = laenge;
conPtr->io_Command = CMD_READ;
SendIO(conPtr); /* bewirkt o. WaitIO Asynchronitaet */
}
void IDCMPCloseClickAbholen(WindowPtr winPtr)
{
ModifyIDCMP(winPtr, IDCMP_CLOSEWINDOW);/*UserPort einr. */
WaitPort(winPtr->UserPort);
ReplyMsg(GetMsg(winPtr->UserPort));
}
void SchreibTest() /* Schreibfarbe waehlen u. Textumbruch*/
/* sowie Scrolling zeigen */
{
int zaehler;
ConWriteStr(conWritePtr,
"\033[1;31mHallo Console! ");
/* ^ ^^ ^ ^
| || | 0x6D = Terminator
| || rot
| |bold
| 0x5B \
ESC / Ersatz fuer CSI
*/
for (zaehler = 0; zaehler < 100; zaehler++)
{
ConWriteStr(conWritePtr, /* bold + Farbe bleibt */
"Hallo Console! ");
}
}
void LeseTest()
{
char buffer[10];
int laenge;
ConWriteStr(conWritePtr,
"\n\033[3;35m** Geben Sie 1 Zeichen ein ** ");
/* ^ ^^ ^ ^
| || | 0x6D = Terminator
| || violett
| |italic
| 0x5B
ESC
*/
laenge = ConReadSync(conReadPtr, buffer, sizeof(buffer));
if (buffer[0] == (char)CSI)
{
buffer[0] = '@'; /* CSI kann nicht ausgegeben werden */
}
ConWriteBuf(conWritePtr, buffer, laenge);
}
void LeseRawEvent() /* spezialisiert auf Keyboard Events */
{
char buffer[400]; /* Je nach Delay dimensionieren */
int index,
laenge;
ConWriteStr(conWritePtr,
"\033[0;31m\n\n\033[1{cl;scl;key;qual;p1;p2;sec;mic|\n");
/* ^ ^^
| |Terminator Raw-Event Anforderung
| RAW-Keyboard Input
ESC
*/
Delay(100);/*um mit Tastatur dev.-int. Puffer zu fuellen*/
laenge = ConReadSync(conReadPtr, buffer, sizeof(buffer));
for (index = 0; index < laenge; index++)
{
if (buffer[index] == (char)CSI)
buffer[index] = (char)012; /* neue Zeile bitte */
} /* anstelle des CSI */
ConWriteBuf(conWritePtr, buffer, laenge); /* alle Zeilen*/
}
void EventCloseClickAbholen(IOStdReqPtr conPtr)
{ char closeEvent[40];
BOOL waitClose = TRUE;
ConWriteStr(conPtr, "\033[1;15}");
/* ^ ^ ^
| | stop reporting events
| disk removed
raw keyboard inputs
*/
ConWriteStr(conPtr, "\033[11{ \nClick CloseGadget\n");
/* ^ ^
| start reporting
Close Gadget Event
*/
do
{
ConReadSync(conPtr, closeEvent, sizeof(closeEvent));
if ((closeEvent[1] == '1') && (closeEvent[2] == '1'))
waitClose = FALSE;
}
while (waitClose);
}
char TwoCharToNum(const char *charPtr)
{
return (charPtr[0] -48) * 10 + (charPtr[1] - 48);
}
void FensterGroesse(char *zeilen, char *spalten)
{
char puffer[20];
int laenge;
ConWriteStr(conWritePtr, "\033[0 q\n"); /*Status Request*/
laenge = ConReadSync /* Fenstergroesse empfangen */
(conReadPtr, puffer, sizeof(puffer));
*zeilen = TwoCharToNum(&puffer[5]);/* Zeilenanzahl holen */
*spalten = TwoCharToNum(&puffer[8]);/* Spaltenanz. holen */
}
void NumToTwoChar(const char *charPtr, char number)
{
charPtr[0] = (char)number / 10 + 48;
charPtr[1] = (char)number % 10 + 48; /* Divisions Rest */
}
void CursorSetzen(char xPos, yPos)
{
char puffer[15];
strcpy(puffer, "\033[00;00H", 11); /* CursPos Huelse */
/* ^ ^
| 5. Byte
2. Byte
*/
NumToTwoChar(&puffer[2], yPos); /* Bytes 2 + 3 ersetzen */
NumToTwoChar(&puffer[5], xPos); /* Bytes 5 + 6 ersetzen */
ConWriteStr(conWritePtr, puffer); /* Cursor positionier.*/
}
void ANSICodeDemo()
{
char cursorReport[10];
char horiz,
vert;
int laenge;
ConWriteStr(conWritePtr, "\033[6n\n"); /* Status Report */
laenge = ConReadSync /* Report empfangen */
(conReadPtr, cursorReport, sizeof(cursorReport));
/* Report umsetzen in Cursor Positionierungs-Befehl */
cursorReport[laenge - 1] = 'H';
cursorReport[laenge] = (char)0; /* in String umwandeln */
FensterGroesse(&vert, &horiz);
ConWriteStr(conWritePtr, "\033[3;34;47m"); /*blau/weiss */
CursorSetzen(horiz / 2 - 6, vert / 2 - 1);
ConWriteStr(conWritePtr, " ");
ConWriteStr(conWritePtr, "\033[1B");/*Cursor 1 line down*/
ConWriteStr(conWritePtr, "\033[11D"); /*11 links bitte */
ConWriteStr(conWritePtr, " AMIGA ");
ConWriteStr(conWritePtr, "\033[1B");/*Cursor 1 line down*/
ConWriteStr(conWritePtr, "\033[11D"); /* Cursor 11 left*/
ConWriteStr(conWritePtr, " ");
/* vor und zurueck scrollen */
ConWriteStr(conWritePtr, "\033[2T");
ConWriteStr(conWritePtr, "\033[4S");
ConWriteStr(conWritePtr, "\033[2T");
/* Cursor-Report modifiziert zurueckschreiben, um Cursor zu
setzen, wo er anfangs war */
ConWriteStr(conWritePtr,cursorReport);
}